package com.hutu.demo.comsumer;

import org.springframework.amqp.core.ExchangeTypes;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.hutu.demo.RabbitMqApplication.EXCHANGE_NAME;
import static com.hutu.demo.RabbitMqApplication.QUEUE_NAME;
import static com.hutu.demo.RabbitMqApplication.QUEUE_NAME_DEAD_LETTER;
import static com.hutu.demo.RabbitMqApplication.QUEUE_NAME_NORMAL;
import static com.hutu.demo.RabbitMqApplication.ROUTING_KEY;

@Component
public class RabbitMqConsumer {


    /*    *//**
     * 创建消费者,并且绑定队列
     *//*
    @RabbitListener(bindings =
    @QueueBinding(
            value = @Queue(value = QUEUE_NAME),
            exchange = @Exchange(name = EXCHANGE_NAME),
            key = {ROUTING_KEY}
    ))
    public void getMessage(String object,Message message, Channel channel) throws IOException {
        // NOTE 手动ACK
        // 获取 deliveryTag 相当于唯一标识
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        try {
            // 消息确认 multiple是否批量
            channel.basicAck(deliveryTag,false);
        } catch (Exception e) {
            // 判断消息是否已经重新投递过了
            Boolean redelivered = message.getMessageProperties().getRedelivered();
            // 拒绝消息 requeue表示是否重新放入队列
            if (redelivered){
                channel.basicNack(deliveryTag, false, false);
            }else {
                channel.basicNack(deliveryTag, false, true);
            }
        }
        System.out.println(object);

    }

    // 死信队列正常队列监听

    */

    /**
     * 创建消费者,并且绑定队列
     *//*
    @RabbitListener(queues = {QUEUE_NAME_NORMAL})
    public void getMessage2(String object,Message message, Channel channel) throws IOException {
        System.out.println(object);
        // 拒绝消息 然后进入死信队列
        channel.basicReject(message.getMessageProperties().getDeliveryTag(),false);
    }

    @RabbitListener(queues = {QUEUE_NAME_DEAD_LETTER})
    public void getMessage3(String object,Message message, Channel channel) throws IOException {
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        System.out.println("死信队列" + object);
        channel.basicNack(deliveryTag, false, false);
    }

    @RabbitListener(queues = {"test_normal"})
    public void getNormalMessage(String object,Message message, Channel channel) {
        System.out.println("getNormalMessage 接收到信息啦~~~~" + object);
    }
    @RabbitListener(queues = {"test_normal"})
    public void getNormalMessage2(String object,Message message, Channel channel) {
        System.out.println("getNormalMessage2 接收到信息啦~~~~" + object);
    }*/


    /*@RabbitListener(queues = {"queue_sports_gossip"})
    public void getRouteSportMessage(String object,Message message, Channel channel) {
        System.out.println("getRouteSportMessage 接收到信息啦~~~~" + object);
    }
    @RabbitListener(queues = {"queue_tech"})
    public void getRouteTechMessage(String object,Message message, Channel channel) {
        System.out.println("getRouteTechMessage 接收到信息啦~~~~" + object);
    }

    @RabbitListener(queues = {"queue_entertainment"})
    public void getTopicEntertainmentMessage(String object,Message message, Channel channel) {
        System.out.println("entertainment 接收到信息啦~~~~" + object);
    }

    @RabbitListener(queues = {"queue_sports"})
    public void getTopicSportsMessage(String object,Message message, Channel channel) {
        System.out.println("sports 接收到信息啦~~~~" + object);
    }*/

    @RabbitListener(queues = {"user_dead_ex_queue"})
    public void getTopicTechsMessage(String object,Message message, Channel channel) {
        System.out.println("techs 接收到信息啦~~~~" + object);
    }


/*    @RabbitListener(bindings =
    @QueueBinding(
            value = @Queue(value = "queue_top_1"),
            exchange = @Exchange(name = "news_topic_exchange_1", type = ExchangeTypes.TOPIC),
            key = {"news.*"}
    ))
    public void getTopicMessage(String object,Message message, Channel channel) {
        System.out.println("news_topic_exchange_1 fanout queue_top_1 message ~" + object);
    }*/
/*
    @RabbitListener(bindings =
    @QueueBinding(
            value = @Queue(value = "queue_sports_gossip"),
            exchange = @Exchange(name = "news_exchange"),
            key = {"sports", "gossip"}
    )*/
/*,containerFactory = "cusSimpleRabbitListenerContainerFactory"*//*
)
    public void getRouteMessage(List<Message> message, Channel channel) throws InterruptedException {
        for (Message msg : message) {
            System.out.println("get message:" + new String(msg.getBody(), StandardCharsets.UTF_8));
        }
        long lastDeliveryTag = message.get(message.size() - 1).getMessageProperties().getDeliveryTag();
        try {
            // 批量接收，deliveryTag小于等于当前tag的就会被手动ack
            // 比如当前 这么多消息里面有deliveryTag 0，1，2，3 ... 当tag为10时，那么小于等于10的就会被ack
            channel.basicAck(lastDeliveryTag,true);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
*/

/*    @RabbitListener(bindings =
    @QueueBinding(
            value = @Queue(value = "queue_sports_gossip"),
            exchange = @Exchange(name = "news_exchange"),
            key = {"sports"}
    ),ackMode = "MANUAL")
    public void getRouteSportsMessage(String object,Message message, Channel channel) {
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        try {
            channel.basicAck(deliveryTag,true);
        } catch (Exception e) {
            try {
                // 为false则拒绝消息，丢掉该消息；为true会重新放回队列，重新消费
                channel.basicReject(deliveryTag, false);
            } catch (IOException ex) {
                throw new RuntimeException(ex);
            }
            throw new RuntimeException(e);
        }
        System.out.println("sports ~: " + object);
    }*/

/*    @RabbitListener(bindings =
    @QueueBinding(
            value = @Queue(value = "queue_tech"),
            exchange = @Exchange(name = "news_exchange"),
            key = {"tech"}
    ),ackMode = "MANUAL")
    public void getRouteTechMessage(String object,Message message, Channel channel) {
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        try {
            channel.basicAck(deliveryTag,true);
        } catch (Exception e) {
            try {
                // 为false则拒绝消息，丢掉该消息；为true会重新放回队列，重新消费
                channel.basicReject(deliveryTag, false);
            } catch (IOException ex) {
                throw new RuntimeException(ex);
            }
            throw new RuntimeException(e);
        }
        System.out.println("tech ~: " + object);
    }*/







//    @RabbitListener(bindings =
//    @QueueBinding(
//            value = @Queue(value = "queue_work_4",durable = "true"),
//            exchange = @Exchange(name = "test_work_1", type = ExchangeTypes.FANOUT,durable = "true")
//    ),ackMode = "MANUAL")
//    public void getWork4Message(String object,Message message, Channel channel) throws IOException {
//        long deliveryTag = message.getMessageProperties().getDeliveryTag();
//        channel.basicAck(deliveryTag,true);
//        System.out.println("----queue_work_4------"+deliveryTag+"-------------");
//        System.out.println("getWork4Message fanout queue_work_4 message ~" + object);
//    }
//    @RabbitListener(bindings =
//    @QueueBinding(
//            value = @Queue(value = "queue_work_3",durable = "true"),
//            exchange = @Exchange(name = "test_work_1", type = ExchangeTypes.FANOUT,durable = "true")
//    ),ackMode = "MANUAL")
//    public void getWork3Message(String object,Message message, Channel channel) throws IOException {
//        long deliveryTag = message.getMessageProperties().getDeliveryTag();
//        channel.basicAck(deliveryTag,true);
//        System.out.println("----queue_work_3------"+deliveryTag+"-------------");
//        System.out.println("getWork4Message fanout queue_work_3 message ~" + object);
//    }

    }
